
using System;
using System.Collections.Generic;


namespace Framework {
    public static partial class ReferencePool
    {
        private sealed class ReferenceCollection
        {
            private readonly Queue<IReference> m_References;
            private readonly Type m_ReferenceType;
            private int m_UsingReferenceCount;

            public ReferenceCollection(Type referenceType)
            {
                this.m_References = new Queue<IReference>();
                this.m_ReferenceType = referenceType;
                this.m_UsingReferenceCount = 0;
            }

            public Type ReferenceType
            {
                get
                {
                    return this.m_ReferenceType;
                }
            }

            public int UnusedReferenceCount
            {
                get
                {
                    return this.m_References.Count;
                }
            }

            public int UsingReferenceCount
            {
                get
                {
                    return this.m_UsingReferenceCount;
                }
            }

            public IReference Fetch()
            {
                this.m_UsingReferenceCount++;
                IReference reference;
                lock (this.m_References)
                {
                    if (this.m_References.Count > 0)
                    {
                        reference = this.m_References.Dequeue();
                        reference.OnFetch();
                        return reference;
                    }
                }
                return (IReference)Activator.CreateInstance(this.m_ReferenceType);
            }

            public void Recycle(IReference reference)
            {
                lock (this.m_References)
                {
                    reference.OnRecycle();
                    this.m_References.Enqueue(reference);
                }
                this.m_UsingReferenceCount--;
            }
            
            public void RemoveAll()
            {
                lock (this.m_References)
                {
                    this.m_References.Clear();
                }
            }
        }
    }
}